diff options
30 files changed, 203 insertions, 1514 deletions
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h index c6e934028..29ee16880 100644 --- a/src/render/backend/abstractrenderer_p.h +++ b/src/render/backend/abstractrenderer_p.h @@ -158,7 +158,7 @@ public: virtual QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() = 0; virtual Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() = 0; virtual Qt3DCore::QAspectJobPtr rayCastingJob() = 0; - virtual Qt3DCore::QAspectJobPtr syncTextureLoadingJob() = 0; + virtual Qt3DCore::QAspectJobPtr syncLoadingJobs() = 0; virtual Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() = 0; virtual void setSceneRoot(Qt3DCore::QBackendNodeFactory *factory, Entity *root) = 0; diff --git a/src/render/backend/handle_types_p.h b/src/render/backend/handle_types_p.h index 035bbfc91..124e6db74 100644 --- a/src/render/backend/handle_types_p.h +++ b/src/render/backend/handle_types_p.h @@ -94,6 +94,7 @@ class Light; class EnvironmentLight; class ComputeCommand; class GLBuffer; +class GLTexture; class RenderStateNode; class Armature; class Skeleton; @@ -132,6 +133,7 @@ typedef Qt3DCore::QHandle<Light> HLight; typedef Qt3DCore::QHandle<EnvironmentLight> HEnvironmentLight; typedef Qt3DCore::QHandle<ComputeCommand> HComputeCommand; typedef Qt3DCore::QHandle<GLBuffer> HGLBuffer; +typedef Qt3DCore::QHandle<GLTexture> HGLTexture; typedef Qt3DCore::QHandle<RenderStateNode> HRenderState; typedef Qt3DCore::QHandle<Armature> HArmature; typedef Qt3DCore::QHandle<Skeleton> HSkeleton; diff --git a/src/render/backend/nodemanagers.cpp b/src/render/backend/nodemanagers.cpp index 584ddd65c..dd82b1a69 100644 --- a/src/render/backend/nodemanagers.cpp +++ b/src/render/backend/nodemanagers.cpp @@ -43,7 +43,6 @@ #include <Qt3DRender/private/scenemanager_p.h> #include <Qt3DRender/private/buffermanager_p.h> #include <Qt3DRender/private/gltexturemanager_p.h> -#include <Qt3DRender/private/texturedatamanager_p.h> #include <Qt3DRender/private/geometryrenderermanager_p.h> #include <Qt3DRender/private/techniquemanager_p.h> #include <Qt3DRender/private/armature_p.h> @@ -71,9 +70,7 @@ NodeManagers::NodeManagers() , m_renderPassManager(new RenderPassManager()) , m_textureManager(new TextureManager()) , m_textureImageManager(new TextureImageManager()) - , m_textureDataManager(new TextureDataManager()) - , m_textureImageDataManager(new TextureImageDataManager()) - , m_glTextureManager(new GLTextureManager(m_textureImageManager, m_textureDataManager, m_textureImageDataManager)) + , m_glTextureManager(new GLTextureManager()) , m_layerManager(new LayerManager()) , m_levelOfDetailManager(new LevelOfDetailManager()) , m_filterKeyManager(new FilterKeyManager()) @@ -117,8 +114,6 @@ NodeManagers::~NodeManagers() delete m_renderPassManager; delete m_glTextureManager; delete m_textureManager; - delete m_textureDataManager; - delete m_textureImageDataManager; delete m_layerManager; delete m_levelOfDetailManager; delete m_filterKeyManager; @@ -224,12 +219,6 @@ TextureManager *NodeManagers::manager<Texture>() const Q_DECL_NOTHROW } template<> -TextureDataManager *NodeManagers::manager<QTextureImageData>() const Q_DECL_NOTHROW -{ - return m_textureDataManager; -} - -template<> LayerManager *NodeManagers::manager<Layer>() const Q_DECL_NOTHROW { return m_layerManager; diff --git a/src/render/backend/nodemanagers_p.h b/src/render/backend/nodemanagers_p.h index 2c4926894..0ad668f98 100644 --- a/src/render/backend/nodemanagers_p.h +++ b/src/render/backend/nodemanagers_p.h @@ -198,8 +198,6 @@ public: inline RenderPassManager *renderPassManager() const Q_DECL_NOEXCEPT { return m_renderPassManager; } inline GLTextureManager *glTextureManager() const Q_DECL_NOEXCEPT { return m_glTextureManager; } inline TextureManager *textureManager() const Q_DECL_NOEXCEPT { return m_textureManager; } - inline TextureDataManager *textureDataManager() const Q_DECL_NOEXCEPT { return m_textureDataManager; } - inline TextureImageDataManager *textureImageDataManager() const Q_DECL_NOEXCEPT { return m_textureImageDataManager; } inline LayerManager *layerManager() const Q_DECL_NOEXCEPT { return m_layerManager; } inline LevelOfDetailManager *levelOfDetailManager() const Q_DECL_NOEXCEPT { return m_levelOfDetailManager; } inline FilterKeyManager *filterKeyManager() const Q_DECL_NOEXCEPT { return m_filterKeyManager; } @@ -243,8 +241,6 @@ private: RenderPassManager *m_renderPassManager; TextureManager *m_textureManager; TextureImageManager *m_textureImageManager; - TextureDataManager *m_textureDataManager; - TextureImageDataManager *m_textureImageDataManager; GLTextureManager *m_glTextureManager; LayerManager *m_layerManager; LevelOfDetailManager *m_levelOfDetailManager; @@ -312,9 +308,6 @@ template<> QT3DRENDERSHARED_PRIVATE_EXPORT TextureManager *NodeManagers::manager<Texture>() const Q_DECL_NOEXCEPT; template<> -QT3DRENDERSHARED_PRIVATE_EXPORT TextureDataManager *NodeManagers::manager<QTextureImageData>() const Q_DECL_NOEXCEPT; - -template<> QT3DRENDERSHARED_PRIVATE_EXPORT LayerManager *NodeManagers::manager<Layer>() const Q_DECL_NOEXCEPT; template<> diff --git a/src/render/backend/resourceaccessor.cpp b/src/render/backend/resourceaccessor.cpp index c6496976a..4f70df436 100644 --- a/src/render/backend/resourceaccessor.cpp +++ b/src/render/backend/resourceaccessor.cpp @@ -42,7 +42,6 @@ #include <private/nodemanagers_p.h> #include <private/texture_p.h> #include <private/rendertargetoutput_p.h> -#include <private/texturedatamanager_p.h> #include <private/gltexturemanager_p.h> #include <private/managers_p.h> #include <private/gltexture_p.h> diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 65906f1ae..f8add3500 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -41,7 +41,6 @@ #include "qrenderaspect_p.h" #include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/texturedatamanager_p.h> #include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/scenemanager_p.h> #include <Qt3DRender/private/geometryrenderermanager_p.h> @@ -113,7 +112,6 @@ #include <Qt3DRender/private/renderlogging_p.h> #include <Qt3DRender/private/nodefunctor_p.h> #include <Qt3DRender/private/framegraphnode_p.h> -#include <Qt3DRender/private/loadtexturedatajob_p.h> #include <Qt3DRender/private/textureimage_p.h> #include <Qt3DRender/private/statesetnode_p.h> #include <Qt3DRender/private/nodraw_p.h> @@ -269,8 +267,7 @@ void QRenderAspectPrivate::registerBackendTypes() // Textures q->registerBackendType<QAbstractTexture>(QSharedPointer<Render::TextureFunctor>::create(m_renderer, m_nodeManagers->textureManager())); q->registerBackendType<QAbstractTextureImage>(QSharedPointer<Render::TextureImageFunctor>::create(m_renderer, - m_nodeManagers->textureImageManager(), - m_nodeManagers->textureImageDataManager())); + m_nodeManagers->textureImageManager())); // Material system q->registerBackendType<QEffect>(QSharedPointer<Render::NodeFunctor<Render::Effect, Render::EffectManager> >::create(m_renderer)); @@ -477,34 +474,16 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time) if (d->m_renderer->isRunning() && d->m_renderer->settings()) { Render::NodeManagers *manager = d->m_renderer->nodeManagers(); - QAspectJobPtr textureLoadingSync = d->m_renderer->syncTextureLoadingJob(); - textureLoadingSync->removeDependency(QWeakPointer<QAspectJob>()); - - // Launch texture generator jobs - const QVector<QTextureImageDataGeneratorPtr> pendingImgGen = manager->textureImageDataManager()->pendingGenerators(); - for (const QTextureImageDataGeneratorPtr &imgGen : pendingImgGen) { - auto loadTextureJob = Render::LoadTextureDataJobPtr::create(imgGen); - textureLoadingSync->addDependency(loadTextureJob); - loadTextureJob->setNodeManagers(manager); - jobs.append(loadTextureJob); - } - const QVector<QTextureGeneratorPtr> pendingTexGen = manager->textureDataManager()->pendingGenerators(); - for (const QTextureGeneratorPtr &texGen : pendingTexGen) { - auto loadTextureJob = Render::LoadTextureDataJobPtr::create(texGen); - textureLoadingSync->addDependency(loadTextureJob); - loadTextureJob->setNodeManagers(manager); - jobs.append(loadTextureJob); - } + QAspectJobPtr loadingJobSync = d->m_renderer->syncLoadingJobs(); + loadingJobSync->removeDependency(QWeakPointer<QAspectJob>()); - // Launch skeleton loader jobs. We join on the syncTextureLoadingJob for now - // which should likely be renamed to something more generic or we introduce - // another synchronizing job for skeleton loading + // Launch skeleton loader jobs once all loading jobs have completed. const QVector<Render::HSkeleton> skeletonsToLoad = manager->skeletonManager()->takeDirtySkeletons(Render::SkeletonManager::SkeletonDataDirty); for (const auto &skeletonHandle : skeletonsToLoad) { auto loadSkeletonJob = Render::LoadSkeletonJobPtr::create(skeletonHandle); loadSkeletonJob->setNodeManagers(manager); - textureLoadingSync->addDependency(loadSkeletonJob); + loadingJobSync->addDependency(loadSkeletonJob); jobs.append(loadSkeletonJob); } diff --git a/src/render/jobs/framecleanupjob.cpp b/src/render/jobs/framecleanupjob.cpp index 7ebe31531..7ebcead37 100644 --- a/src/render/jobs/framecleanupjob.cpp +++ b/src/render/jobs/framecleanupjob.cpp @@ -43,7 +43,6 @@ #include <private/entity_p.h> #include <private/shaderdata_p.h> #include <private/managers_p.h> -#include <private/texturedatamanager_p.h> #include <private/sphere_p.h> #include <Qt3DRender/private/job_common_p.h> diff --git a/src/render/jobs/job_common_p.h b/src/render/jobs/job_common_p.h index e776d452d..9c83624b8 100644 --- a/src/render/jobs/job_common_p.h +++ b/src/render/jobs/job_common_p.h @@ -100,7 +100,7 @@ namespace JobTypes { UpdateMeshTriangleList, FilterCompatibleTechniques, UpdateLevelOfDetail, - SyncTextureLoading, + SyncLoadingJobs, LoadSkeleton, UpdateSkinningPalette, ProximityFiltering, diff --git a/src/render/jobs/jobs.pri b/src/render/jobs/jobs.pri index 472531681..2181e4a95 100644 --- a/src/render/jobs/jobs.pri +++ b/src/render/jobs/jobs.pri @@ -4,7 +4,6 @@ HEADERS += \ $$PWD/updateworldtransformjob_p.h \ $$PWD/loadscenejob_p.h \ $$PWD/framecleanupjob_p.h \ - $$PWD/loadtexturedatajob_p.h \ $$PWD/loadbufferjob_p.h \ $$PWD/loadgeometryjob_p.h \ $$PWD/calcboundingvolumejob_p.h \ @@ -37,7 +36,6 @@ SOURCES += \ $$PWD/updateworldtransformjob.cpp \ $$PWD/loadscenejob.cpp \ $$PWD/framecleanupjob.cpp \ - $$PWD/loadtexturedatajob.cpp \ $$PWD/loadbufferjob.cpp \ $$PWD/loadgeometryjob.cpp \ $$PWD/calcboundingvolumejob.cpp \ diff --git a/src/render/jobs/loadtexturedatajob.cpp b/src/render/jobs/loadtexturedatajob.cpp deleted file mode 100644 index 55232d74f..000000000 --- a/src/render/jobs/loadtexturedatajob.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "loadtexturedatajob_p.h" -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/texturedatamanager_p.h> -#include <Qt3DRender/qtextureimagedata.h> -#include <Qt3DRender/private/job_common_p.h> -#include <Qt3DRender/private/qtextureimagedata_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -LoadTextureDataJob::LoadTextureDataJob(const QTextureGeneratorPtr &texGen) - : m_texGen(texGen) - , m_imgDataGen(nullptr) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadTextureData, 0); -} - -LoadTextureDataJob::LoadTextureDataJob(const QTextureImageDataGeneratorPtr &imgDataGen) - : m_texGen(nullptr) - , m_imgDataGen(imgDataGen) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadTextureData, 0); -} - -LoadTextureDataJob::~LoadTextureDataJob() -{ -} - -void LoadTextureDataJob::run() -{ - if (m_texGen) { - QTextureDataPtr texData = (*m_texGen)(); - m_manager->textureDataManager()->assignData(m_texGen, texData); - } - if (m_imgDataGen) { - QTextureImageDataPtr imgData = (*m_imgDataGen)(); - m_manager->textureImageDataManager()->assignData(m_imgDataGen, imgData); - } -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/jobs/loadtexturedatajob_p.h b/src/render/jobs/loadtexturedatajob_p.h deleted file mode 100644 index 607068712..000000000 --- a/src/render/jobs/loadtexturedatajob_p.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_LOADTEXTUREDATAJOB_H -#define QT3DRENDER_RENDER_LOADTEXTUREDATAJOB_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qnodeid.h> -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DRender/qtexturegenerator.h> -#include <Qt3DRender/qtextureimagedatagenerator.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class NodeManagers; - -class LoadTextureDataJob : public Qt3DCore::QAspectJob -{ -public: - LoadTextureDataJob(const QTextureGeneratorPtr &texGen); - LoadTextureDataJob(const QTextureImageDataGeneratorPtr &imgDataGen); - ~LoadTextureDataJob(); - - inline void setNodeManagers(NodeManagers *manager) { m_manager = manager; } - -protected: - void run() final; - -private: - QTextureGeneratorPtr m_texGen; - QTextureImageDataGeneratorPtr m_imgDataGen; - - NodeManagers *m_manager; -}; - -typedef QSharedPointer<LoadTextureDataJob> LoadTextureDataJobPtr; - -} // namespace Render - -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_LOADTEXTUREDATAJOB_H diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index d8b1409e1..be08abbd0 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -199,7 +199,7 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_sendTextureChangesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendTextureChangesToFrontend(); }, JobTypes::SendTextureChangesToFrontend)) , m_sendSetFenceHandlesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend)) , m_introspectShaderJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { reloadDirtyShaders(); }, JobTypes::DirtyShaderGathering)) - , m_syncTextureLoadingJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncTextureLoading)) + , m_syncLoadingJobs(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncLoadingJobs)) , m_ownedContext(false) , m_offscreenHelper(nullptr) #if QT_CONFIG(qt3d_profile_jobs) @@ -222,12 +222,8 @@ Renderer::Renderer(QRenderAspect::RenderType type) m_rayCastingJob->addDependency(m_expandBoundingVolumeJob); // m_calculateBoundingVolumeJob's dependency on m_updateTreeEnabledJob is set in renderBinJobs - // Dirty texture gathering depends on m_syncTextureLoadingJob - // m_syncTextureLoadingJob will depend on the texture loading jobs - m_textureGathererJob->addDependency(m_syncTextureLoadingJob); - // Ensures all skeletons are loaded before we try to update them - m_updateSkinningPaletteJob->addDependency(m_syncTextureLoadingJob); + m_updateSkinningPaletteJob->addDependency(m_syncLoadingJobs); // All world stuff depends on the RenderEntity's localBoundingVolume m_updateLevelOfDetailJob->addDependency(m_updateMeshTriangleListJob); @@ -501,9 +497,11 @@ void Renderer::releaseGraphicsResources() if (context->makeCurrent(offscreenSurface)) { // Clean up the graphics context and any resources - const QVector<GLTexture*> activeTextures = m_nodesManager->glTextureManager()->activeResources(); - for (GLTexture *tex : activeTextures) - tex->destroyGLTexture(); + const QVector<HGLTexture> activeTexturesHandles = m_nodesManager->glTextureManager()->activeHandles(); + for (const HGLTexture &textureHandle : activeTexturesHandles) { + GLTexture *tex = m_nodesManager->glTextureManager()->data(textureHandle); + tex->destroy(); + } // Do the same thing with buffers const QVector<HGLBuffer> activeBuffers = m_nodesManager->glBufferManager()->activeHandles(); @@ -1297,7 +1295,8 @@ void Renderer::updateGLResources() if (texture == nullptr) continue; - // Create or Update GLTexture + // Create or Update GLTexture (the GLTexture instance is created if required + // and all things that can take place without a GL context are done here) updateTexture(texture); } // We want to upload textures data at this point as the SubmissionThread and @@ -1305,15 +1304,18 @@ void Renderer::updateGLResources() // GLTexture if (m_submissionContext != nullptr) { GLTextureManager *glTextureManager = m_nodesManager->glTextureManager(); - const QVector<GLTexture *> glTextures = glTextureManager->activeResources(); + const QVector<HGLTexture> glTextureHandles = glTextureManager->activeHandles(); // Upload texture data - for (GLTexture *glTexture : glTextures) { + for (const HGLTexture &glTextureHandle : glTextureHandles) { + GLTexture *glTexture = glTextureManager->data(glTextureHandle); + + // We create/update the actual GL texture using the GL context at this point const GLTexture::TextureUpdateInfo info = glTexture->createOrUpdateGLTexture(); // GLTexture creation provides us width/height/format ... information // for textures which had not initially specified these information (TargetAutomatic...) // Gather these information and store them to be distributed by a change next frame - const QNodeIdVector referenceTextureIds = glTextureManager->referencedTextureIds(glTexture); + const QNodeIdVector referenceTextureIds = { glTextureManager->texNodeIdForGLTexture.value(glTexture) }; // Store properties and referenceTextureIds if (info.wasUpdated) { Texture::TextureUpdateInfo updateInfo; @@ -1324,14 +1326,10 @@ void Renderer::updateGLResources() } } } + + // Record ids of texture to cleanup while we are still blocking the aspect thread + m_textureIdsToCleanup += m_nodesManager->textureManager()->takeTexturesIdsToCleanup(); } - // When Textures are cleaned up, their id is saved so that they can be - // cleaned up in the render thread Note: we perform this step in second so - // that the previous updateTexture call has a chance to find a shared - // texture and avoid possible destroying recreating a new texture - const QVector<Qt3DCore::QNodeId> cleanedUpTextureIds = m_nodesManager->textureManager()->takeTexturesIdsToCleanup(); - for (const Qt3DCore::QNodeId textureCleanedUpId: cleanedUpTextureIds) - cleanupTexture(textureCleanedUpId); } // Render Thread @@ -1339,92 +1337,56 @@ void Renderer::updateTexture(Texture *texture) { // Check that the current texture images are still in place, if not, do not update const bool isValid = texture->isValid(m_nodesManager->textureImageManager()); - if (!isValid) + if (!isValid) { + qWarning() << Q_FUNC_INFO << "QTexture referencing invalid QTextureImages"; return; - - // For implementing unique, non-shared, non-cached textures. - // for now, every texture is shared by default except if: - // - texture is reference by a render attachment - // - texture is referencing a shared texture id - bool isUnique = texture->sharedTextureId() > 0; - - if (!isUnique) { - // TO DO: Update the vector once per frame (or in a job) - const QVector<HAttachment> activeRenderTargetOutputs = m_nodesManager->attachmentManager()->activeHandles(); - // A texture is unique if it's being reference by a render target output - for (const HAttachment &attachmentHandle : activeRenderTargetOutputs) { - RenderTargetOutput *attachment = m_nodesManager->attachmentManager()->data(attachmentHandle); - if (attachment->textureUuid() == texture->peerId()) { - isUnique = true; - break; - } - } } + // All textures are unique, if you instanciate twice the exact same texture + // this will create 2 identical GLTextures, no sharing will take place + // Try to find the associated GLTexture for the backend Texture GLTextureManager *glTextureManager = m_nodesManager->glTextureManager(); GLTexture *glTexture = glTextureManager->lookupResource(texture->peerId()); - auto createOrUpdateGLTexture = [=] () { - if (isUnique) - glTextureManager->createUnique(texture); - else - glTextureManager->getOrCreateShared(texture); - texture->unsetDirty(); - }; - // No GLTexture associated yet -> create it if (glTexture == nullptr) { - createOrUpdateGLTexture(); - return; + glTexture = glTextureManager->getOrCreateResource(texture->peerId()); + glTextureManager->texNodeIdForGLTexture.insert(glTexture, texture->peerId()); } - // if this texture is a shared texture, we might need to look for a new TextureImpl - // and abandon the old one - if (glTextureManager->isShared(glTexture)) { - glTextureManager->abandon(glTexture, texture->peerId()); - // Note: if isUnique is true, a once shared texture will become unique - createOrUpdateGLTexture(); - return; - } - - // this texture node is the only one referring to the GLTexture. - // we could thus directly modify the texture. Instead, for non-unique textures, - // we first see if there is already a matching texture present. - if (!isUnique) { - GLTexture *newSharedTex = glTextureManager->findMatchingShared(texture); - if (newSharedTex && newSharedTex != glTexture) { - glTextureManager->abandon(glTexture, texture->peerId()); - glTextureManager->adoptShared(newSharedTex, texture); - texture->unsetDirty(); - return; - } - } - - // we hold a reference to a unique or exclusive access to a shared texture - // we can thus modify the texture directly. + // Update GLTexture to match Texture instance const Texture::DirtyFlags dirtyFlags = texture->dirtyFlags(); - if (dirtyFlags.testFlag(Texture::DirtySharedTextureId) && - !glTextureManager->setSharedTextureId(glTexture, texture->sharedTextureId())) - qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setSharedTextureId failed, should be non-shared"; + if (dirtyFlags.testFlag(Texture::DirtySharedTextureId)) + glTexture->setSharedTextureId(texture->sharedTextureId()); - if (dirtyFlags.testFlag(Texture::DirtyProperties) && - !glTextureManager->setProperties(glTexture, texture->properties())) - qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setProperties failed, should be non-shared"; + if (dirtyFlags.testFlag(Texture::DirtyProperties)) + glTexture->setProperties(texture->properties()); - if (dirtyFlags.testFlag(Texture::DirtyParameters) && - !glTextureManager->setParameters(glTexture, texture->parameters())) - qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setParameters failed, should be non-shared"; + if (dirtyFlags.testFlag(Texture::DirtyParameters)) + glTexture->setParameters(texture->parameters()); // Will make the texture requestUpload - if (dirtyFlags.testFlag(Texture::DirtyImageGenerators) && - !glTextureManager->setImages(glTexture, texture->textureImageIds())) - qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setGenerators failed, should be non-shared"; + if (dirtyFlags.testFlag(Texture::DirtyImageGenerators)) { + const QNodeIdVector textureImageIds = texture->textureImageIds(); + QVector<GLTexture::Image> images; + images.reserve(textureImageIds.size()); + // TODO: Move this into GLTexture directly + for (const QNodeId textureImageId : textureImageIds) { + const TextureImage *img = m_nodesManager->textureImageManager()->lookupResource(textureImageId); + if (img == nullptr) { + qWarning() << Q_FUNC_INFO << "invalid TextureImage handle"; + } else { + GLTexture::Image glImg {img->dataGenerator(), img->layer(), img->mipLevel(), img->face()}; + images.push_back(glImg); + } + } + glTexture->setImages(images); + } // Will make the texture requestUpload - if (dirtyFlags.testFlag(Texture::DirtyDataGenerator) && - !glTextureManager->setGenerator(glTexture, texture->dataGenerator())) - qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setGenerator failed, should be non-shared"; + if (dirtyFlags.testFlag(Texture::DirtyDataGenerator)) + glTexture->setGenerator(texture->dataGenerator()); // Unset the dirty flag on the texture texture->unsetDirty(); @@ -1436,8 +1398,11 @@ void Renderer::cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId) GLTextureManager *glTextureManager = m_nodesManager->glTextureManager(); GLTexture *glTexture = glTextureManager->lookupResource(cleanedUpTextureId); - if (glTexture != nullptr) - glTextureManager->abandon(glTexture, cleanedUpTextureId); + // Destroying the GLTexture implicitely also destroy the GL resources + if (glTexture != nullptr) { + glTextureManager->releaseResource(cleanedUpTextureId); + glTextureManager->texNodeIdForGLTexture.remove(glTexture); + } } // Called by SubmitRenderView @@ -1808,6 +1773,8 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() renderBinJobs.push_back(m_expandBoundingVolumeJob); } + // TO DO: Conditionally add if skeletons dirty + renderBinJobs.push_back(m_syncLoadingJobs); m_updateSkinningPaletteJob->setDirtyJoints(m_nodesManager->jointManager()->dirtyJoints()); renderBinJobs.push_back(m_updateSkinningPaletteJob); renderBinJobs.push_back(m_updateLevelOfDetailJob); @@ -1821,10 +1788,8 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() if (dirtyBitsForFrame & AbstractRenderer::BuffersDirty) renderBinJobs.push_back(m_bufferGathererJob); - if (dirtyBitsForFrame & AbstractRenderer::TexturesDirty) { - renderBinJobs.push_back(m_syncTextureLoadingJob); + if (dirtyBitsForFrame & AbstractRenderer::TexturesDirty) renderBinJobs.push_back(m_textureGathererJob); - } // Layer cache is dependent on layers, layer filters and the enabled flag @@ -1920,9 +1885,9 @@ QAspectJobPtr Renderer::rayCastingJob() return m_rayCastingJob; } -QAspectJobPtr Renderer::syncTextureLoadingJob() +QAspectJobPtr Renderer::syncLoadingJobs() { - return m_syncTextureLoadingJob; + return m_syncLoadingJobs; } QAspectJobPtr Renderer::expandBoundingVolumeJob() @@ -2244,12 +2209,11 @@ void Renderer::cleanGraphicsResources() for (Qt3DCore::QNodeId bufferId : buffersToRelease) m_submissionContext->releaseBuffer(bufferId); - // Delete abandoned textures - const QVector<GLTexture*> abandonedTextures = m_nodesManager->glTextureManager()->takeAbandonedTextures(); - for (GLTexture *tex : abandonedTextures) { - tex->destroyGLTexture(); - delete tex; - } + // When Textures are cleaned up, their id is saved so that they can be + // cleaned up in the render thread + const QVector<Qt3DCore::QNodeId> cleanedUpTextureIds = std::move(m_textureIdsToCleanup); + for (const Qt3DCore::QNodeId textureCleanedUpId: cleanedUpTextureIds) + cleanupTexture(textureCleanedUpId); // Delete abandoned VAOs m_abandonedVaosMutex.lock(); diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index 93d6fdbfa..a80a862f7 100644 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ b/src/render/renderers/opengl/renderer/renderer_p.h @@ -204,7 +204,7 @@ public: QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override; Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override; Qt3DCore::QAspectJobPtr rayCastingJob() override; - Qt3DCore::QAspectJobPtr syncTextureLoadingJob() override; + Qt3DCore::QAspectJobPtr syncLoadingJobs() override; Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() override; QVector<Qt3DCore::QAspectJobPtr> createRenderBufferJobs() const; @@ -218,7 +218,7 @@ public: inline UpdateLevelOfDetailJobPtr updateLevelOfDetailJob() const { return m_updateLevelOfDetailJob; } inline UpdateMeshTriangleListJobPtr updateMeshTriangleListJob() const { return m_updateMeshTriangleListJob; } inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; } - inline SynchronizerJobPtr textureLoadSyncJob() const { return m_syncTextureLoadingJob; } + inline SynchronizerJobPtr syncLoadingJobs() const { return m_syncLoadingJobs; } inline UpdateSkinningPaletteJobPtr updateSkinningPaletteJob() const { return m_updateSkinningPaletteJob; } inline IntrospectShadersJobPtr introspectShadersJob() const { return m_introspectShaderJob; } inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; } @@ -382,7 +382,7 @@ private: GenericLambdaJobPtr<std::function<void ()>> m_sendSetFenceHandlesToFrontendJob; IntrospectShadersJobPtr m_introspectShaderJob; - SynchronizerJobPtr m_syncTextureLoadingJob; + SynchronizerJobPtr m_syncLoadingJobs; void lookForAbandonedVaos(); void lookForDirtyBuffers(); @@ -401,6 +401,7 @@ private: QVector<HTexture> m_dirtyTextures; QVector<QPair<Texture::TextureUpdateInfo, Qt3DCore::QNodeIdVector>> m_updatedTextureProperties; QVector<QPair<Qt3DCore::QNodeId, GLFence>> m_updatedSetFences; + Qt3DCore::QNodeIdVector m_textureIdsToCleanup; bool m_ownedContext; diff --git a/src/render/renderers/opengl/textures/gltexture.cpp b/src/render/renderers/opengl/textures/gltexture.cpp index 42deb4c2a..4561e5ebf 100644 --- a/src/render/renderers/opengl/textures/gltexture.cpp +++ b/src/render/renderers/opengl/textures/gltexture.cpp @@ -49,7 +49,6 @@ #include <Qt3DRender/qtexturedata.h> #include <Qt3DRender/qtextureimagedata.h> #include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/texturedatamanager_p.h> #include <Qt3DRender/private/qabstracttexture_p.h> #include <Qt3DRender/private/renderbuffer_p.h> #include <Qt3DRender/private/qtextureimagedata_p.h> @@ -69,39 +68,42 @@ using namespace Qt3DCore; namespace Qt3DRender { namespace Render { -GLTexture::GLTexture(TextureDataManager *texDataMgr, - TextureImageDataManager *texImgDataMgr, - const QTextureGeneratorPtr &texGen, - bool unique) - : m_unique(unique) - , m_gl(nullptr) +namespace { + +// This uploadGLData where the data is a fullsize subimage +// as QOpenGLTexture doesn't allow partial subimage uploads +void uploadGLData(QOpenGLTexture *glTex, + int level, int layer, QOpenGLTexture::CubeMapFace face, + const QByteArray &bytes, const QTextureImageDataPtr &data) +{ + if (data->isCompressed()) { + glTex->setCompressedData(level, layer, face, bytes.size(), bytes.constData()); + } else { + QOpenGLPixelTransferOptions uploadOptions; + uploadOptions.setAlignment(1); + glTex->setData(level, layer, face, data->pixelFormat(), data->pixelType(), bytes.constData(), &uploadOptions); + } +} + +} // anonymous + + +GLTexture::GLTexture() + : m_gl(nullptr) , m_renderBuffer(nullptr) - , m_textureDataManager(texDataMgr) - , m_textureImageDataManager(texImgDataMgr) - , m_dataFunctor(texGen) + , m_dataFunctor() , m_pendingDataFunctor(nullptr) , m_sharedTextureId(-1) , m_externalRendering(false) { - // make sure texture generator is executed - // this is needed when Texture have the TargetAutomatic - // to ensure they are loaded before trying to instantiate the QOpenGLTexture - if (!texGen.isNull()) - m_textureDataManager->requestData(texGen, this); } GLTexture::~GLTexture() { - destroyGLTexture(); } -void GLTexture::destroyResources() -{ - if (m_dataFunctor) - m_textureDataManager->releaseData(m_dataFunctor, this); -} - -void GLTexture::destroyGLTexture() +// Must be called from RenderThread with active GL context +void GLTexture::destroy() { delete m_gl; m_gl = nullptr; @@ -109,13 +111,22 @@ void GLTexture::destroyGLTexture() m_renderBuffer = nullptr; m_dirtyFlags.store(0); - - destroyResources(); + m_sharedTextureId = -1; + m_externalRendering = false; + m_dataFunctor.reset(); + m_pendingDataFunctor = nullptr; + + m_actualTarget = QAbstractTexture::Target1D; + m_properties = {}; + m_parameters = {}; + m_textureData.reset(); + m_images.clear(); + m_imageData.clear(); } bool GLTexture::loadTextureDataFromGenerator() { - m_textureData = m_textureDataManager->getData(m_dataFunctor); + m_textureData = m_dataFunctor->operator()(); // if there is a texture generator, most properties will be defined by it if (m_textureData) { if (m_properties.target != QAbstractTexture::TargetAutomatic) @@ -143,7 +154,7 @@ void GLTexture::loadTextureDataFromImages() { int maxMipLevel = 0; for (const Image &img : qAsConst(m_images)) { - const QTextureImageDataPtr imgData = m_textureImageDataManager->getData(img.generator); + const QTextureImageDataPtr imgData = img.generator->operator()(); // imgData may be null in the following cases: // - Texture is created with TextureImages which have yet to be // loaded (skybox where you don't yet know the path, source set by @@ -285,7 +296,7 @@ RenderBuffer *GLTexture::getOrCreateRenderBuffer() QMutexLocker locker(&m_textureMutex); if (m_dataFunctor && !m_textureData) { - m_textureData = m_textureDataManager->getData(m_dataFunctor); + m_textureData = m_dataFunctor->operator()(); if (m_textureData) { if (m_properties.target != QAbstractTexture::TargetAutomatic) qWarning() << "[Qt3DRender::GLTexture] [renderbuffer] When a texture provides a generator, it's target is expected to be TargetAutomatic"; @@ -318,6 +329,13 @@ RenderBuffer *GLTexture::getOrCreateRenderBuffer() return m_renderBuffer; } +// This must be called from the RenderThread +// So GLTexture release from the manager can only be done from that thread +void GLTexture::cleanup() +{ + destroy(); +} + void GLTexture::setParameters(const TextureParameters ¶ms) { QMutexLocker locker(&m_textureMutex); @@ -359,19 +377,9 @@ void GLTexture::setImages(const QVector<Image> &images) void GLTexture::setGenerator(const QTextureGeneratorPtr &generator) { - // Note: we do not compare if the generator is different - // as in some cases we may want to reset the same generator to force a reload - // e.g when using remote urls for textures - if (m_dataFunctor) - m_textureDataManager->releaseData(m_dataFunctor, this); - m_textureData.reset(); m_dataFunctor = generator; - - if (m_dataFunctor) { - m_textureDataManager->requestData(m_dataFunctor, this); - requestUpload(); - } + requestUpload(); } void GLTexture::setSharedTextureId(int textureId) @@ -471,19 +479,6 @@ QOpenGLTexture *GLTexture::buildGLTexture() return glTex; } -static void uploadGLData(QOpenGLTexture *glTex, - int level, int layer, QOpenGLTexture::CubeMapFace face, - const QByteArray &bytes, const QTextureImageDataPtr &data) -{ - if (data->isCompressed()) { - glTex->setCompressedData(level, layer, face, bytes.size(), bytes.constData()); - } else { - QOpenGLPixelTransferOptions uploadOptions; - uploadOptions.setAlignment(1); - glTex->setData(level, layer, face, data->pixelFormat(), data->pixelType(), bytes.constData(), &uploadOptions); - } -} - void GLTexture::uploadGLTextureData() { // Upload all QTexImageData set by the QTextureGenerator @@ -518,6 +513,9 @@ void GLTexture::uploadGLTextureData() static_cast<QOpenGLTexture::CubeMapFace>(m_images[i].face), bytes, imgData); } + // Free up image data once content has been uploaded + // Note: if data functor stores the data, this won't really free anything though + m_imageData.clear(); } void GLTexture::updateGLTextureParameters() diff --git a/src/render/renderers/opengl/textures/gltexture_p.h b/src/render/renderers/opengl/textures/gltexture_p.h index 66f66926c..4dd78513a 100644 --- a/src/render/renderers/opengl/textures/gltexture_p.h +++ b/src/render/renderers/opengl/textures/gltexture_p.h @@ -96,11 +96,7 @@ class RenderBuffer; class Q_AUTOTEST_EXPORT GLTexture { public: - GLTexture(TextureDataManager *texDataMgr, - TextureImageDataManager *texImgDataMgr, - const QTextureGeneratorPtr &texGen, - bool unique); - + GLTexture(); ~GLTexture(); /** @@ -120,8 +116,6 @@ public: inline bool operator!=(const Image &o) const { return !(*this == o); } }; - inline bool isUnique() const { return m_unique; } - inline TextureProperties properties() const { return m_properties; } inline TextureParameters parameters() const { return m_parameters; } inline QTextureGeneratorPtr textureGenerator() const { return m_dataFunctor; } @@ -157,17 +151,10 @@ public: */ RenderBuffer *getOrCreateRenderBuffer(); - /** - * @brief Make sure to call this before calling the dtor - */ - void destroyGLTexture(); - // Called by TextureDataManager when it has new texture data from - // a generator that needs to be uploaded. - void requestUpload() - { - setDirtyFlag(TextureData, true); - } + void destroy(); + + void cleanup(); bool isDirty() { @@ -189,18 +176,6 @@ public: return m_externalRendering; } -protected: - template<class APITexture, class APITextureImage> - friend class APITextureManager; - - /* - * These methods are to be accessed from the GLTextureManager. - * The renderer and the texture backend nodes can only modify Textures - * through the GLTextureManager. - * - * The methods should only be called for unique textures, or textures - * that are not shared between multiple nodes. - */ void setParameters(const TextureParameters ¶ms); void setProperties(const TextureProperties &props); void setImages(const QVector<Image> &images); @@ -216,6 +191,12 @@ private: SharedTextureId = 0x08 // texture id from shared context }; + + void requestUpload() + { + setDirtyFlag(TextureData, true); + } + bool testDirtyFlag(DirtyFlag flag) { return m_dirtyFlags.load() & flag; @@ -237,16 +218,12 @@ private: void introspectPropertiesFromSharedTextureId(); void destroyResources(); - bool m_unique; QAtomicInt m_dirtyFlags; QMutex m_textureMutex; QMutex m_externalRenderingMutex; QOpenGLTexture *m_gl; RenderBuffer *m_renderBuffer; - TextureDataManager *m_textureDataManager; - TextureImageDataManager *m_textureImageDataManager; - // target which is actually used for GL texture QAbstractTexture::Target m_actualTarget; TextureProperties m_properties; diff --git a/src/render/renderers/opengl/textures/gltexturemanager_p.h b/src/render/renderers/opengl/textures/gltexturemanager_p.h index 1c8b49911..335af136c 100644 --- a/src/render/renderers/opengl/textures/gltexturemanager_p.h +++ b/src/render/renderers/opengl/textures/gltexturemanager_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include <Qt3DRender/private/apitexturemanager_p.h> +#include <Qt3DCore/private/qresourcemanager_p.h> #include <Qt3DRender/private/gltexture_p.h> QT_BEGIN_NAMESPACE @@ -59,21 +59,20 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT GLTextureManager : public APITextureManager<GLTexture, GLTexture::Image> +class Q_AUTOTEST_EXPORT GLTextureManager : public Qt3DCore::QResourceManager< + GLTexture, + Qt3DCore::QNodeId, + Qt3DCore::NonLockingPolicy> { public: - explicit GLTextureManager(TextureImageManager *textureImageManager, - TextureDataManager *textureDataManager, - TextureImageDataManager *textureImageDataManager) - : APITextureManager<GLTexture, GLTexture::Image>(textureImageManager, - textureDataManager, - textureImageDataManager) - {} + QHash<GLTexture *, Qt3DCore::QNodeId> texNodeIdForGLTexture; }; } // namespace Render } // namespace Qt3DRender +Q_DECLARE_RESOURCE_INFO(Qt3DRender::Render::GLTexture, Q_REQUIRES_CLEANUP) + QT_END_NAMESPACE #endif // QT3DRENDER_RENDER_GLTEXTUREMANAGER_H diff --git a/src/render/texture/apitexturemanager_p.h b/src/render/texture/apitexturemanager_p.h deleted file mode 100644 index 79dc9af94..000000000 --- a/src/render/texture/apitexturemanager_p.h +++ /dev/null @@ -1,411 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_APITEXTUREMANAGER_P_H -#define QT3DRENDER_RENDER_APITEXTUREMANAGER_P_H - -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/texturedatamanager_p.h> -#include <Qt3DRender/private/textureimage_p.h> -#include <Qt3DRender/private/texture_p.h> -#include <Qt3DRender/qtexturegenerator.h> -#include <Qt3DRender/qtextureimagedatagenerator.h> - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -// Manages instances of APITexture. This includes sharing between multiple -// Texture nodes, updating APITextures and deleting abandoned instances. -template <class APITexture, class APITextureImage> -class APITextureManager -{ -public: - - explicit APITextureManager(TextureImageManager *textureImageManager, - TextureDataManager *textureDataManager, - TextureImageDataManager *textureImageDataManager) - : m_textureImageManager(textureImageManager) - , m_textureDataManager(textureDataManager) - , m_textureImageDataManager(textureImageDataManager) - { - } - - ~APITextureManager() - { - qDeleteAll(activeResources()); - m_nodeIdToGLTexture.clear(); - m_sharedTextures.clear(); - m_updatedTextures.clear(); - } - - // Used to retrieve all resources that needs to be destroyed on the GPU - QVector<APITexture *> activeResources() const - { - // Active Resources are - // all shared textures - // all unique textures - // all textures that haven't yet been destroyed - // Note: updatedTextures only referenced textures in one of these 3 vectors - return m_sharedTextures.keys().toVector() + m_uniqueTextures + m_abandonedTextures; - } - - APITexture *lookupResource(Qt3DCore::QNodeId textureId) const - { - return m_nodeIdToGLTexture.value(textureId); - } - - Qt3DCore::QNodeIdVector referencedTextureIds(APITexture *apiTexture) const - { - return m_sharedTextures.value(apiTexture); - } - - // Returns a APITexture that matches the given QTexture node. Will make sure - // that texture data generator jobs are launched, if necessary. The APITexture - // may be shared between multiple texture backend nodes - APITexture *getOrCreateShared(const Texture *node) - { - Q_ASSERT(node); - - APITexture *shared = findMatchingShared(node); - - // no matching shared texture was found; create a new one: - if (shared == nullptr) - shared = createTexture(node, false); - - // store texture node to shared texture relationship - adoptShared(shared, node); - - return shared; - } - - // Store that the shared texture references node - void adoptShared(APITexture *sharedApiTexture, const Texture *node) - { - if (!m_sharedTextures[sharedApiTexture].contains(node->peerId())) { - m_sharedTextures[sharedApiTexture].push_back(node->peerId()); - m_nodeIdToGLTexture.insert(node->peerId(), sharedApiTexture); - } - } - - // If there is already a shared texture with the properties of the given - // texture node, return this instance, else NULL. - // Note: the reference to the texture node is added if the shared texture - // wasn't referencing it already - APITexture *findMatchingShared(const Texture *node) - { - Q_ASSERT(node); - - // search for existing texture - const auto end = m_sharedTextures.end(); - for (auto it = m_sharedTextures.begin(); it != end; ++it) - if (isSameTexture(it.key(), node)) - return it.key(); - return nullptr; - } - - // Returns a APITexture that matches the given QTexture node. Will make sure - // that texture data generator jobs are launched, if necessary. - APITexture *createUnique(const Texture *node) - { - Q_ASSERT(node); - APITexture *uniqueTex = createTexture(node, true); - m_uniqueTextures.push_back(uniqueTex); - m_nodeIdToGLTexture.insert(node->peerId(), uniqueTex); - return uniqueTex; - } - - // De-associate the given APITexture from the backend node. If the texture - // is no longer referenced by any other node, it will be deleted. - void abandon(APITexture *tex, const Qt3DCore::QNodeId nodeId) - { - APITexture *apiTexture = m_nodeIdToGLTexture.take(nodeId); - Q_ASSERT(tex == apiTexture); - - if (Q_UNLIKELY(!apiTexture)) { - qWarning() << "[Qt3DRender::TextureManager] abandon: could not find Texture"; - return; - } - - if (tex->isUnique()) { - m_uniqueTextures.removeAll(apiTexture); - m_abandonedTextures.push_back(apiTexture); - } else { - QVector<Qt3DCore::QNodeId> &referencedTextureNodes = m_sharedTextures[apiTexture]; - referencedTextureNodes.removeAll(nodeId); - - // If no texture nodes is referencing the shared APITexture, remove it - if (referencedTextureNodes.empty()) { - m_abandonedTextures.push_back(apiTexture); - m_sharedTextures.remove(apiTexture); - tex->destroyResources(); - } - } - } - - // Change the properties of the given texture, if it is a non-shared texture - // Returns true, if it was changed successfully, false otherwise - bool setProperties(APITexture *tex, const TextureProperties &props) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - tex->setProperties(props); - m_updatedTextures.push_back(tex); - - return true; - } - - // Change the parameters of the given texture, if it is a non-shared texture - // Returns true, if it was changed successfully, false otherwise - bool setParameters(APITexture *tex, const TextureParameters ¶ms) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - tex->setParameters(params); - m_updatedTextures.push_back(tex); - - return true; - } - - // Change the texture images of the given texture, if it is a non-shared texture - // Return true, if it was changed successfully, false otherwise - bool setImages(APITexture *tex, const Qt3DCore::QNodeIdVector &imageIds) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - // create Image structs - QVector<APITextureImage> texImgs = texImgsFromNodes(imageIds); - if (texImgs.size() != imageIds.size()) - return false; - - tex->setImages(texImgs); - m_updatedTextures.push_back(tex); - - return true; - } - - // Change the texture data generator for given texture, if it is a non-shared texture - // Return true, if it was changed successfully, false otherwise - bool setGenerator(APITexture *tex, const QTextureGeneratorPtr &generator) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - tex->setGenerator(generator); - m_updatedTextures.push_back(tex); - - return true; - } - - // Change the texture's referenced texture Id from a shared context - bool setSharedTextureId(APITexture *tex, int textureId) - { - Q_ASSERT(tex); - - if (isShared(tex)) - return false; - - tex->setSharedTextureId(textureId); - m_updatedTextures.push_back(tex); - return true; - } - - // Retrieves abandoned textures. This should be regularly called from the OpenGL thread - // to make sure needed GL resources are de-allocated. - QVector<APITexture*> takeAbandonedTextures() - { - return std::move(m_abandonedTextures); - } - - // Retrieves textures that have been modified - QVector<APITexture*> takeUpdatedTextures() - { - return std::move(m_updatedTextures); - } - - // Returns whether the given APITexture is shared between multiple TextureNodes - bool isShared(APITexture *impl) - { - Q_ASSERT(impl); - - if (impl->isUnique()) - return false; - - auto it = m_sharedTextures.constFind(impl); - if (it == m_sharedTextures.cend()) - return false; - - return it.value().size() > 1; - } - -private: - - // Check if the given APITexture matches the TextureNode - bool isSameTexture(const APITexture *tex, const Texture *texNode) - { - // make sure there either are no texture generators, or the two are the same - if (tex->textureGenerator().isNull() != texNode->dataGenerator().isNull()) - return false; - if (!tex->textureGenerator().isNull() && !(*tex->textureGenerator() == *texNode->dataGenerator())) - return false; - - // make sure the image generators are the same - const QVector<APITextureImage> texImgGens = tex->images(); - const Qt3DCore::QNodeIdVector texImgs = texNode->textureImageIds(); - if (texImgGens.size() != texImgs.size()) - return false; - for (int i = 0; i < texImgGens.size(); ++i) { - const TextureImage *img = m_textureImageManager->lookupResource(texImgs[i]); - Q_ASSERT(img != nullptr); - if (!(*img->dataGenerator() == *texImgGens[i].generator) - || img->layer() != texImgGens[i].layer - || img->face() != texImgGens[i].face - || img->mipLevel() != texImgGens[i].mipLevel) - return false; - } - - // if the texture has a texture generator, this generator will mostly determine - // the properties of the texture. - if (!tex->textureGenerator().isNull()) - return (tex->properties().generateMipMaps == texNode->properties().generateMipMaps - && tex->parameters() == texNode->parameters()); - - // if it doesn't have a texture generator, but texture image generators, - // few more properties will influence the texture type - if (!texImgGens.empty()) - return (tex->properties().target == texNode->properties().target - && tex->properties().format == texNode->properties().format - && tex->properties().generateMipMaps == texNode->properties().generateMipMaps - && tex->parameters() == texNode->parameters()); - - // texture without images - return tex->properties() == texNode->properties() - && tex->parameters() == texNode->parameters(); - } - - // Create APITexture from given TextureNode. Also make sure the generators - // will be executed by jobs soon. - APITexture *createTexture(const Texture *node, bool unique) - { - // create Image structs - const QVector<APITextureImage> texImgs = texImgsFromNodes(node->textureImageIds()); - if (texImgs.empty() && !node->textureImageIds().empty()) - return nullptr; - - // no matching shared texture was found, create a new one - APITexture *newTex = new APITexture(m_textureDataManager, m_textureImageDataManager, node->dataGenerator(), unique); - newTex->setProperties(node->properties()); - newTex->setParameters(node->parameters()); - newTex->setImages(texImgs); - newTex->setSharedTextureId(node->sharedTextureId()); - - m_updatedTextures.push_back(newTex); - - return newTex; - } - - QVector<APITextureImage> texImgsFromNodes(const Qt3DCore::QNodeIdVector &imageIds) const - { - QVector<APITextureImage> ret; - ret.resize(imageIds.size()); - - for (int i = 0; i < imageIds.size(); ++i) { - const TextureImage *img = m_textureImageManager->lookupResource(imageIds[i]); - if (!img) { - qWarning() << "[Qt3DRender::TextureManager] invalid TextureImage handle"; - return QVector<APITextureImage>(); - } - - ret[i].generator = img->dataGenerator(); - ret[i].face = img->face(); - ret[i].layer = img->layer(); - ret[i].mipLevel = img->mipLevel(); - } - - return ret; - } - - TextureImageManager *m_textureImageManager; - TextureDataManager *m_textureDataManager; - TextureImageDataManager *m_textureImageDataManager; - - /* each non-unique texture is associated with a number of Texture nodes referencing it */ - QHash<APITexture*, QVector<Qt3DCore::QNodeId>> m_sharedTextures; - - // Texture id -> APITexture (both shared and unique ones) - QHash<Qt3DCore::QNodeId, APITexture *> m_nodeIdToGLTexture; - - QVector<APITexture*> m_uniqueTextures; - QVector<APITexture*> m_abandonedTextures; - QVector<APITexture*> m_updatedTextures; -}; - - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE - - -#endif // QT3DRENDER_RENDER_APITEXTUREMANAGER_P_H diff --git a/src/render/texture/qabstracttexture.cpp b/src/render/texture/qabstracttexture.cpp index 17c4a8f11..5b11243c4 100644 --- a/src/render/texture/qabstracttexture.cpp +++ b/src/render/texture/qabstracttexture.cpp @@ -94,12 +94,18 @@ void QAbstractTexturePrivate::setDataFunctor(const QTextureGeneratorPtr &generat \since 5.5 \brief A base class to be used to provide textures. - The QAbstractTexture class shouldn't be used directly but rather - through one of its subclasses. Each subclass implements a given texture - target (2D, 2DArray, 3D, CubeMap ...) Each subclass provides a set of - functors for each layer, cube map face and mipmap level. In turn the - backend uses those functor to properly fill a corresponding OpenGL texture - with data. + The QAbstractTexture class shouldn't be used directly but rather through + one of its subclasses. Each subclass implements a given texture target (2D, + 2DArray, 3D, CubeMap ...) Each subclass provides a set of functors for each + layer, cube map face and mipmap level. In turn the backend uses those + functor to properly fill a corresponding OpenGL texture with data. It is + expected the functor does as minimal processing as possible so as not + to slow down textures generation and upload. If the content of a texture is + the result of a slow procedural generation process, it is recommended not + to implement this directly in a functor. + + All textures are unique. If you instantiate twice the same texture this + will create 2 identical textures on the GPU, no sharing will take place. */ /*! diff --git a/src/render/texture/qtexture.cpp b/src/render/texture/qtexture.cpp index cf93f872f..fc62b76ff 100644 --- a/src/render/texture/qtexture.cpp +++ b/src/render/texture/qtexture.cpp @@ -56,7 +56,6 @@ #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/texture_p.h> #include <Qt3DRender/private/qurlhelper_p.h> -#include <Qt3DRender/private/texturedatamanager_p.h> #include <Qt3DRender/private/gltexturemanager_p.h> QT_BEGIN_NAMESPACE @@ -925,7 +924,8 @@ QTextureDataPtr QTextureFromSourceGenerator::operator ()() auto downloadService = Qt3DCore::QDownloadHelperService::getService(m_engine); Qt3DCore::QDownloadRequestPtr request(new TextureDownloadRequest(sharedFromThis(), m_url, - m_engine)); + m_engine, + m_texture)); downloadService->submitRequest(request); } return generatedData; @@ -974,10 +974,12 @@ QTextureDataPtr QTextureFromSourceGenerator::operator ()() TextureDownloadRequest::TextureDownloadRequest(const QTextureFromSourceGeneratorPtr &functor, const QUrl &source, - Qt3DCore::QAspectEngine *engine) + Qt3DCore::QAspectEngine *engine, + Qt3DCore::QNodeId texNodeId) : Qt3DCore::QDownloadRequest(source) , m_functor(functor) , m_engine(engine) + , m_texNodeId(texNodeId) { } @@ -992,46 +994,23 @@ void TextureDownloadRequest::onCompleted() if (!d_aspect) return; - // Find all textures which share the same functor - // Note: this should be refactored to not pull in API specific managers - // but texture sharing forces us to do that currently - Render::TextureDataManager *textureDataManager = d_aspect->m_nodeManagers->textureDataManager(); - const QVector<Render::GLTexture *> referencedGLTextures = textureDataManager->referencesForGenerator(m_functor); - - // We should have at most 1 GLTexture referencing this - // Since all textures having the same source should have the same functor == same GLTexture - Q_ASSERT(referencedGLTextures.size() <= 1); - - Render::GLTexture *glTex = referencedGLTextures.size() > 0 ? referencedGLTextures.first() : nullptr; - if (glTex == nullptr) - return; - - Render::GLTextureManager *glTextureManager = d_aspect->m_nodeManagers->glTextureManager(); - Qt3DCore::QNodeIdVector referencingTexturesIds = glTextureManager->referencedTextureIds(glTex); - - Render::TextureManager *textureManager = d_aspect->m_nodeManagers->textureManager(); - for (const Qt3DCore::QNodeId texId : referencingTexturesIds) { - Render::Texture *texture = textureManager->lookupResource(texId); - if (texture != nullptr) { - // Each texture has a QTextureFunctor which matches m_functor; - // Update m_sourceData on each functor as we don't know which one - // is used as the reference for texture sharing + Render::Texture *texture = textureManager->lookupResource(m_texNodeId); + if (texture == nullptr) + return; - QTextureFromSourceGeneratorPtr oldGenerator = qSharedPointerCast<QTextureFromSourceGenerator>(texture->dataGenerator()); + QTextureFromSourceGeneratorPtr oldGenerator = qSharedPointerCast<QTextureFromSourceGenerator>(texture->dataGenerator()); - // We create a new functor - // Which is a copy of the old one + the downloaded sourceData - auto newGenerator = QTextureFromSourceGeneratorPtr::create(*oldGenerator); + // We create a new functor + // Which is a copy of the old one + the downloaded sourceData + auto newGenerator = QTextureFromSourceGeneratorPtr::create(*oldGenerator); - // Set raw data on functor so that it can really load something - newGenerator->m_sourceData = m_data; + // Set raw data on functor so that it can really load something + newGenerator->m_sourceData = m_data; - // Set new generator on texture - // it implictely marks the texture as dirty so that the functor runs again with the downloaded data - texture->setDataGenerator(newGenerator); - } - } + // Set new generator on texture + // it implictely marks the texture as dirty so that the functor runs again with the downloaded data + texture->setDataGenerator(newGenerator); } /*! diff --git a/src/render/texture/qtexture_p.h b/src/render/texture/qtexture_p.h index 087480340..726bf2c01 100644 --- a/src/render/texture/qtexture_p.h +++ b/src/render/texture/qtexture_p.h @@ -84,13 +84,15 @@ class Q_AUTOTEST_EXPORT TextureDownloadRequest : public Qt3DCore::QDownloadReque public: TextureDownloadRequest(const QTextureFromSourceGeneratorPtr &functor, const QUrl &url, - Qt3DCore::QAspectEngine *engine); + Qt3DCore::QAspectEngine *engine, + Qt3DCore::QNodeId texNodeId); void onCompleted() override; private: QTextureFromSourceGeneratorPtr m_functor; Qt3DCore::QAspectEngine *m_engine; + Qt3DCore::QNodeId m_texNodeId; }; class Q_AUTOTEST_EXPORT QTextureFromSourceGenerator : public QTextureGenerator, diff --git a/src/render/texture/texture.pri b/src/render/texture/texture.pri index 0d520a9ec..0115a649e 100644 --- a/src/render/texture/texture.pri +++ b/src/render/texture/texture.pri @@ -8,7 +8,6 @@ HEADERS += \ $$PWD/qtextureimage_p.h \ $$PWD/qtexturewrapmode.h \ $$PWD/texture_p.h \ - $$PWD/texturedatamanager_p.h \ $$PWD/textureimage_p.h \ $$PWD/qabstracttexture.h \ $$PWD/qabstracttexture_p.h \ @@ -20,8 +19,7 @@ HEADERS += \ $$PWD/qtexturegenerator.h \ $$PWD/qtexture_p.h \ $$PWD/qpaintedtextureimage.h \ - $$PWD/qpaintedtextureimage_p.h \ - $$PWD/apitexturemanager_p.h + $$PWD/qpaintedtextureimage_p.h SOURCES += \ $$PWD/qabstracttextureimage.cpp \ diff --git a/src/render/texture/texturedatamanager_p.h b/src/render/texture/texturedatamanager_p.h deleted file mode 100644 index 9319a64e0..000000000 --- a/src/render/texture/texturedatamanager_p.h +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_TEXTUREDATAMANAGER_H -#define QT3DRENDER_RENDER_TEXTUREDATAMANAGER_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QMutex> -#include <QMutexLocker> -#include <Qt3DRender/qtexture.h> -#include <Qt3DRender/qtextureimagedata.h> -#include <Qt3DRender/qtexturegenerator.h> -#include <Qt3DRender/qtextureimagedatagenerator.h> -#include <Qt3DRender/private/gltexture_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -/** - * The texture data managers associates each texture data generator - * with the data objects generated by them. That is, either - * - * QTextureImageDataGenerator -> QTextureImageData, or - * QTextureGenerator -> QTextureData - * - * This way, texture classes only need to refer to the texture functors used. - * Aspect jobs will make sure that at the start of each frame, all generators - * registered with the GeneratorDataManagers have been executed. - * - * This guarantees that no texture data generator is executed twice. - * - * Each Generator is associated with a number of textures that reference it. - * If the last texture disassociates from a generator, the QTextureData will - * be deleted. - */ -template <class GeneratorPtr, class DataPtr, class ReferencedType> -class GeneratorDataManager -{ -public: - GeneratorDataManager() {} - - /*! - * If no data for the given generator exists, make sure that the - * generators are executed the next frame. Reference generator by - * given texture - * - * Returns true if the Entry for a given generator had to be created - */ - bool requestData(const GeneratorPtr &generator, ReferencedType r) - { - QMutexLocker lock(&m_mutex); - - Entry *entry = findEntry(generator); - const bool needsToBeCreated = (entry == nullptr); - if (needsToBeCreated) - entry = createEntry(generator); - Q_ASSERT(entry); - if (!entry->referencingObjects.contains(r)) - entry->referencingObjects.push_back(r); - return needsToBeCreated; - } - - QVector<ReferencedType> referencesForGenerator(const GeneratorPtr &generator) - { - QMutexLocker lock(&m_mutex); - - Entry *entry = findEntry(generator); - if (entry == nullptr) - return {}; - return entry->referencingObjects; - } - - - /*! - * Dereference given generator from texture. If no other textures still reference - * the generator, the associated data will be deleted - */ - void releaseData(const GeneratorPtr &generator, ReferencedType r) - { - QMutexLocker lock(&m_mutex); - - const auto end = m_data.end(); - for (auto it = m_data.begin(); it != end; ++it) { - Entry &entry = *it; - if (*entry.generator == *generator) { - entry.referencingObjects.removeAll(r); - // delete, if that was the last reference - if (entry.referencingObjects.empty()) { - m_data.erase(it); - return; - } - } - } - } - - /*! - * Return data associated with given generator, if existent - */ - DataPtr getData(const GeneratorPtr &generator) - { - QMutexLocker lock(&m_mutex); - - const Entry *entry = findEntry(generator); - return entry ? entry->data : DataPtr(); - } - - /*! - * Returns all generators that were not yet executed - */ - QVector<GeneratorPtr> pendingGenerators() - { - QMutexLocker lock(&m_mutex); - - QVector<GeneratorPtr> ret; - for (const Entry &entry : m_data) - if (!entry.data && !ret.contains(entry.generator)) - ret.push_back(entry.generator); - return ret; - } - - /*! - * Assigns a piece of data to the generator that was used to - * create it. - */ - void assignData(const GeneratorPtr &generator, const DataPtr &data) - { - QMutexLocker lock(&m_mutex); - - Entry *entry = findEntry(generator); - if (!entry) { - qWarning() << "[TextureDataManager] assignData() called with non-existent generator"; - return; - } - entry->data = data; - } - - bool contains(const GeneratorPtr &generator) - { - return findEntry(generator) != nullptr; - } - -private: - - struct Entry { - GeneratorPtr generator; - QVector<ReferencedType> referencingObjects; - DataPtr data; - }; - - /*! - * Helper function: return entry for given generator if it exists, nullptr - * otherwise. - */ - Entry* findEntry(const GeneratorPtr &generator) - { - for (int i = 0, sz = m_data.size(); i < sz; ++i) - if (*m_data[i].generator == *generator) - return &m_data[i]; - return nullptr; - } - - Entry *createEntry(const GeneratorPtr &generator) - { - Entry newEntry; - newEntry.generator = generator; - - m_data.push_back(newEntry); - return &m_data.back(); - } - - QMutex m_mutex; - QVector<Entry> m_data; -}; - -class Q_AUTOTEST_EXPORT TextureDataManager - : public GeneratorDataManager<QTextureGeneratorPtr, QTextureDataPtr, GLTexture*> -{ -}; - -class Q_AUTOTEST_EXPORT TextureImageDataManager - : public GeneratorDataManager<QTextureImageDataGeneratorPtr, QTextureImageDataPtr, Qt3DCore::QNodeId> -{ -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // TEXTUREDATAMANAGER_H diff --git a/src/render/texture/textureimage.cpp b/src/render/texture/textureimage.cpp index 880562b87..87cfdbca6 100644 --- a/src/render/texture/textureimage.cpp +++ b/src/render/texture/textureimage.cpp @@ -42,7 +42,6 @@ #include <Qt3DRender/qtextureimage.h> #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/qabstracttextureimage_p.h> -#include <Qt3DRender/private/texturedatamanager_p.h> QT_BEGIN_NAMESPACE @@ -57,7 +56,6 @@ TextureImage::TextureImage() , m_layer(0) , m_mipLevel(0) , m_face(QAbstractTexture::CubeMapPositiveX) - , m_textureImageDataManager(nullptr) { } @@ -67,10 +65,7 @@ TextureImage::~TextureImage() void TextureImage::cleanup() { - if (m_generator) { - m_textureImageDataManager->releaseData(m_generator, peerId()); - m_generator.reset(); - } + m_generator.reset(); m_dirty = false; m_layer = 0; m_mipLevel = 0; @@ -86,10 +81,6 @@ void TextureImage::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr m_face = data.face; m_generator = data.generator; m_dirty = true; - - // Request functor upload - if (m_generator) - m_textureImageDataManager->requestData(m_generator, peerId()); } void TextureImage::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) @@ -104,13 +95,7 @@ void TextureImage::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } else if (propertyChange->propertyName() == QByteArrayLiteral("face")) { m_face = static_cast<QAbstractTexture::CubeMapFace>(propertyChange->value().toInt()); } else if (propertyChange->propertyName() == QByteArrayLiteral("dataGenerator")) { - // Release ref to generator - if (m_generator) - m_textureImageDataManager->releaseData(m_generator, peerId()); m_generator = propertyChange->value().value<QTextureImageDataGeneratorPtr>(); - // Request functor upload - if (m_generator) - m_textureImageDataManager->requestData(m_generator, peerId()); } m_dirty = true; } @@ -125,18 +110,15 @@ void TextureImage::unsetDirty() } TextureImageFunctor::TextureImageFunctor(AbstractRenderer *renderer, - TextureImageManager *textureImageManager, - TextureImageDataManager *textureImageDataManager) + TextureImageManager *textureImageManager) : m_renderer(renderer) , m_textureImageManager(textureImageManager) - , m_textureImageDataManager(textureImageDataManager) { } Qt3DCore::QBackendNode *TextureImageFunctor::create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const { TextureImage *backend = m_textureImageManager->getOrCreateResource(change->subjectId()); - backend->setTextureImageDataManager(m_textureImageDataManager); backend->setRenderer(m_renderer); return backend; } diff --git a/src/render/texture/textureimage_p.h b/src/render/texture/textureimage_p.h index 19801ee77..490fe4432 100644 --- a/src/render/texture/textureimage_p.h +++ b/src/render/texture/textureimage_p.h @@ -77,11 +77,6 @@ public: ~TextureImage(); void cleanup(); - - void setTextureImageDataManager(TextureImageDataManager *dataManager) { m_textureImageDataManager = dataManager; } - - TextureImageDataManager *textureImageDataManager() const { return m_textureImageDataManager; } - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; inline int layer() const { return m_layer; } @@ -99,16 +94,13 @@ private: int m_mipLevel; QAbstractTexture::CubeMapFace m_face; QTextureImageDataGeneratorPtr m_generator; - - TextureImageDataManager *m_textureImageDataManager; }; class TextureImageFunctor : public Qt3DCore::QBackendNodeMapper { public: explicit TextureImageFunctor(AbstractRenderer *renderer, - TextureImageManager *textureImageManager, - TextureImageDataManager *textureImageDataManager); + TextureImageManager *textureImageManager); Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const final; Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const final; @@ -117,7 +109,6 @@ public: private: AbstractRenderer *m_renderer; TextureImageManager *m_textureImageManager; - TextureImageDataManager *m_textureImageDataManager; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/tests/auto/render/commons/testrenderer.h b/tests/auto/render/commons/testrenderer.h index f19b3211b..124e30492 100644 --- a/tests/auto/render/commons/testrenderer.h +++ b/tests/auto/render/commons/testrenderer.h @@ -61,7 +61,7 @@ public: QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); } Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override { return Qt3DCore::QAspectJobPtr(); } Qt3DCore::QAspectJobPtr rayCastingJob() override { return Qt3DCore::QAspectJobPtr(); } - Qt3DCore::QAspectJobPtr syncTextureLoadingJob() override { return Qt3DCore::QAspectJobPtr(); } + Qt3DCore::QAspectJobPtr syncLoadingJobs() override { return Qt3DCore::QAspectJobPtr(); } Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() override { return Qt3DCore::QAspectJobPtr(); } void setSceneRoot(Qt3DCore::QBackendNodeFactory *factory, Qt3DRender::Render::Entity *root) override { Q_UNUSED(factory); Q_UNUSED(root); } Qt3DRender::Render::Entity *sceneRoot() const override { return nullptr; } diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro index b737d328b..da9d884ed 100644 --- a/tests/auto/render/render.pro +++ b/tests/auto/render/render.pro @@ -64,7 +64,6 @@ qtConfig(private_tests) { qabstracttexture \ qabstracttextureimage \ qrendersettings \ - texturedatamanager \ rendertarget \ transform \ computecommand \ diff --git a/tests/auto/render/renderer/tst_renderer.cpp b/tests/auto/render/renderer/tst_renderer.cpp index e77b59bf6..00ded02b0 100644 --- a/tests/auto/render/renderer/tst_renderer.cpp +++ b/tests/auto/render/renderer/tst_renderer.cpp @@ -171,6 +171,7 @@ private Q_SLOTS: 1 + // cleanupJob 1 + // VAOGatherer 1 + // updateSkinningPaletteJob + 1 + // SyncLoadingJobs singleRenderViewJobCount); // Only valid for the first call to renderBinJobs(), since subsequent calls won't have the renderqueue reset renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); @@ -185,6 +186,7 @@ private Q_SLOTS: 1 + // cleanupJob 1 + // VAOGatherer 1 + // updateSkinningPaletteJob + 1 + // SyncLoadingJobs 1); // EntityEnabledDirty renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); @@ -202,6 +204,7 @@ private Q_SLOTS: 1 + // UpdateWorldBoundingVolume 1 + // UpdateShaderDataTransform 1 + // updateSkinningPaletteJob + 1 + // SyncLoadingJobs 1); // ExpandBoundingVolumeJob renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); @@ -218,6 +221,7 @@ private Q_SLOTS: 1 + // CalculateBoundingVolumeJob 1 + // UpdateMeshTriangleListJob 1 + // updateSkinningPaletteJob + 1 + // SyncLoadingJobs 1); // ExpandBoundingVolumeJob renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); @@ -232,6 +236,7 @@ private Q_SLOTS: 1 + // cleanupJob 1 + // VAOGatherer 1 + // updateSkinningPaletteJob + 1 + // SyncLoadingJobs 1 + // CalculateBoundingVolumeJob 1 + // UpdateMeshTriangleListJob 1); // BufferGathererJob @@ -249,7 +254,7 @@ private Q_SLOTS: 1 + // VAOGatherer 1 + // TexturesGathererJob 1 + // updateSkinningPaletteJob - 1); // SyncTexturesGathererJob + 1); // SyncLoadingJobs renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); @@ -262,7 +267,8 @@ private Q_SLOTS: 1 + // updateLevelOfDetailJob 1 + // cleanupJob 1 + // VAOGatherer - 1); // updateSkinningPaletteJob + 1 + // updateSkinningPaletteJob + 1); // SyncLoadingJobs renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); @@ -281,12 +287,12 @@ private Q_SLOTS: 1 + // CalculateBoundingVolumeJob 1 + // UpdateMeshTriangleListJob 1 + // updateSkinningPaletteJob + 1 + // SyncLoadingJobs 1 + // updateLevelOfDetailJob 1 + // cleanupJob 1 + // VAOGatherer 1 + // BufferGathererJob 1 + // TexturesGathererJob - 1 + // SyncTextureLoadingJob 1); // UpdateEntityLayersJob renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); diff --git a/tests/auto/render/texturedatamanager/texturedatamanager.pro b/tests/auto/render/texturedatamanager/texturedatamanager.pro deleted file mode 100644 index cb6f2ee64..000000000 --- a/tests/auto/render/texturedatamanager/texturedatamanager.pro +++ /dev/null @@ -1,12 +0,0 @@ -TEMPLATE = app - -TARGET = tst_texturedatamanager - -QT += 3dcore 3dcore-private 3drender 3drender-private testlib - -CONFIG += testcase - -SOURCES += tst_texturedatamanager.cpp - -include(../../core/common/common.pri) -include(../commons/commons.pri) diff --git a/tests/auto/render/texturedatamanager/tst_texturedatamanager.cpp b/tests/auto/render/texturedatamanager/tst_texturedatamanager.cpp deleted file mode 100644 index eb7177adf..000000000 --- a/tests/auto/render/texturedatamanager/tst_texturedatamanager.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include <QtTest/QTest> -#include <Qt3DRender/private/texturedatamanager_p.h> - -namespace { - -class FakeGenerator -{ -public: - explicit FakeGenerator(const QString &name) - : m_name(name) - {} - - bool operator==(const FakeGenerator &other) const - { - return other.m_name == m_name; - } - - bool operator!=(const FakeGenerator &other) const - { - return !(other == *this); - } -private: - QString m_name; -}; -typedef QSharedPointer<FakeGenerator> FakeGeneratorPtr; - -class FakeData -{ -public: - explicit FakeData(int value) - : m_value(value) - { - Q_UNUSED(m_value); - } - -private: - int m_value; -}; -typedef QSharedPointer<FakeData> FakeDataPtr; - - -struct FakeAPITexture -{ - void requestUpload() {} -}; - -using Manager = Qt3DRender::Render::GeneratorDataManager<FakeGeneratorPtr, FakeDataPtr, FakeAPITexture*>; - -} // anonymous - -class tst_TextureDataManager : public QObject -{ - Q_OBJECT - -private Q_SLOTS: - - void checkAssumptions() - { - // GIVEN - FakeGeneratorPtr zr1(FakeGeneratorPtr::create(QStringLiteral("ZR1"))); - FakeGeneratorPtr z06(FakeGeneratorPtr::create(QStringLiteral("Z06"))); - - // THEN - QVERIFY(*zr1 == *zr1); - QVERIFY(*z06 == *z06); - QVERIFY(*zr1 != *z06); - QVERIFY(*z06 != *zr1); - } - - void checkRequestDataShouldCreate() - { - // GIVEN - Manager manager; - FakeGeneratorPtr generator(FakeGeneratorPtr::create(QStringLiteral("ZR1"))); - FakeAPITexture texture; - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 0); - - // WHEN - manager.requestData(generator, &texture); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 1); - } - - void checkRequestDataAlreadyExistingGenerator() - { - // GIVEN - Manager manager; - FakeGeneratorPtr generator(FakeGeneratorPtr::create(QStringLiteral("ZR1"))); - FakeGeneratorPtr generatorClone(FakeGeneratorPtr::create(QStringLiteral("ZR1"))); - FakeAPITexture texture; - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 0); - - // WHEN - for (int i = 0; i < 5; ++i) - manager.requestData(generator, &texture); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 1); - - // WHEN - for (int i = 0; i < 5; ++i) - manager.requestData(generatorClone, &texture); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 1); - } - - - void checkReleaseDataInvalidEntry() - { - // GIVEN - Manager manager; - FakeGeneratorPtr generator(FakeGeneratorPtr::create(QStringLiteral("ZR1"))); - FakeAPITexture texture; - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 0); - - // WHEN - manager.releaseData(generator, &texture); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 0); - // and should not crash - } - - void checkReleaseDataValidEntry() - { - // GIVEN - Manager manager; - FakeGeneratorPtr generator(FakeGeneratorPtr::create(QStringLiteral("ZR1"))); - FakeAPITexture texture; - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 0); - - // WHEN - manager.requestData(generator, &texture); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 1); - - // WHEN - manager.releaseData(generator, &texture); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 0); - } - - void checkAssignGetData() - { - // GIVEN - Manager manager; - FakeGeneratorPtr generator(FakeGeneratorPtr::create(QStringLiteral("ZR1"))); - FakeDataPtr data(FakeDataPtr::create(883)); - FakeAPITexture texture; - - // WHEN - manager.assignData(generator, data); - - // THEN - QVERIFY(manager.getData(generator).isNull()); - - // WHEN - manager.requestData(generator, &texture); - manager.assignData(generator, data); - - // THEN - QCOMPARE(data, manager.getData(generator)); - } - - void checkPendingGenerators() - { - // GIVEN - Manager manager; - FakeGeneratorPtr generator(FakeGeneratorPtr::create(QStringLiteral("ZR1"))); - FakeDataPtr data(FakeDataPtr::create(883)); - FakeAPITexture texture; - - // WHEN - manager.requestData(generator, &texture); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 1); - QCOMPARE(manager.pendingGenerators().first(), generator); - - // WHEN - manager.requestData(generator, &texture); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 1); - QCOMPARE(manager.pendingGenerators().first(), generator); - - // WHEN - FakeGeneratorPtr generator2(FakeGeneratorPtr::create(QStringLiteral("Z06"))); - FakeAPITexture texture2; - manager.requestData(generator2, &texture2); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 2); - QCOMPARE(manager.pendingGenerators().first(), generator); - QCOMPARE(manager.pendingGenerators().last(), generator2); - - // WHEN - manager.releaseData(generator, &texture); - - // THEN - QCOMPARE(manager.pendingGenerators().size(), 1); - QCOMPARE(manager.pendingGenerators().first(), generator2); - } -}; - -QTEST_MAIN(tst_TextureDataManager) - -#include "tst_texturedatamanager.moc" diff --git a/tests/auto/render/textures/tst_textures.cpp b/tests/auto/render/textures/tst_textures.cpp index 390853e77..1cd11b153 100644 --- a/tests/auto/render/textures/tst_textures.cpp +++ b/tests/auto/render/textures/tst_textures.cpp @@ -36,7 +36,6 @@ #include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/texture_p.h> #include <Qt3DRender/private/textureimage_p.h> -#include <Qt3DRender/private/texturedatamanager_p.h> #include <Qt3DRender/private/nodemanagers_p.h> #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/gltexturemanager_p.h> @@ -188,8 +187,7 @@ class tst_RenderTextures : public Qt3DCore::QBackendNodeTester Qt3DRender::Render::Texture *createBackendTexture(Qt3DRender::QAbstractTexture *frontend, Qt3DRender::Render::TextureManager *texMgr, - Qt3DRender::Render::TextureImageManager *texImgMgr, - Qt3DRender::Render::TextureImageDataManager *texImgDataManager) + Qt3DRender::Render::TextureImageManager *texImgMgr) { Qt3DRender::Render::Texture *backend = texMgr->getOrCreateResource(frontend->id()); simulateInitialization(frontend, backend); @@ -199,7 +197,6 @@ class tst_RenderTextures : public Qt3DCore::QBackendNodeTester // make sure TextureImageManager has backend node for this QTextureImage if (!texImgMgr->contains(texImgFrontend->id())) { Qt3DRender::Render::TextureImage *texImgBackend = texImgMgr->getOrCreateResource(texImgFrontend->id()); - texImgBackend->setTextureImageDataManager(texImgDataManager); simulateInitialization(texImgFrontend, texImgBackend); } backend->addTextureImage(texImgFrontend->id()); @@ -212,6 +209,7 @@ private Q_SLOTS: void shouldCreateSameGLTextures() { + QSKIP("Texture Sharing is now disabled"); QScopedPointer<Qt3DRender::Render::NodeManagers> mgrs(new Qt3DRender::Render::NodeManagers()); Qt3DRender::Render::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous); renderer.setNodeManagers(mgrs.data()); @@ -223,12 +221,10 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::Texture *bt1a = createBackendTexture(tex1a, mgrs->textureManager(), - mgrs->textureImageManager(), - mgrs->textureImageDataManager()); + mgrs->textureImageManager()); Qt3DRender::Render::Texture *bt1b = createBackendTexture(tex1b, mgrs->textureManager(), - mgrs->textureImageManager(), - mgrs->textureImageDataManager()); + mgrs->textureImageManager()); renderer.updateTexture(bt1a); renderer.updateTexture(bt1b); @@ -258,8 +254,7 @@ private Q_SLOTS: for (auto *t : textures) { Qt3DRender::Render::Texture *backendTexture = createBackendTexture(t, mgrs->textureManager(), - mgrs->textureImageManager(), - mgrs->textureImageDataManager()); + mgrs->textureImageManager()); backend.push_back(backendTexture); renderer.updateTexture(backendTexture); } @@ -308,12 +303,10 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::Texture *bt1 = createBackendTexture(tex1a, mgrs->textureManager(), - mgrs->textureImageManager(), - mgrs->textureImageDataManager()); + mgrs->textureImageManager()); Qt3DRender::Render::Texture *bt2 = createBackendTexture(tex1b, mgrs->textureManager(), - mgrs->textureImageManager(), - mgrs->textureImageDataManager()); + mgrs->textureImageManager()); // THEN QCOMPARE(bt1->sharedTextureId(), 1); QCOMPARE(bt2->sharedTextureId(), 1); @@ -339,12 +332,10 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::Texture *bt1 = createBackendTexture(tex1a, mgrs->textureManager(), - mgrs->textureImageManager(), - mgrs->textureImageDataManager()); + mgrs->textureImageManager()); Qt3DRender::Render::Texture *bt2 = createBackendTexture(tex1b, mgrs->textureManager(), - mgrs->textureImageManager(), - mgrs->textureImageDataManager()); + mgrs->textureImageManager()); // THEN QCOMPARE(bt1->sharedTextureId(), 1); QCOMPARE(bt2->sharedTextureId(), 2); @@ -381,8 +372,7 @@ private Q_SLOTS: for (auto *t : textures) { Qt3DRender::Render::Texture *backendTexture = createBackendTexture(t, mgrs->textureManager(), - mgrs->textureImageManager(), - mgrs->textureImageDataManager()); + mgrs->textureImageManager()); backend.push_back(backendTexture); renderer.updateTexture(backendTexture); } @@ -406,32 +396,6 @@ private Q_SLOTS: QVERIFY(!(*idg1a == *idg2)); QCOMPARE(*tg1a, *tg1b); QVERIFY(!(*tg1a == *tg2)); - Qt3DRender::Render::TextureImageDataManager *imgDataMgr = mgrs->textureImageDataManager(); - Qt3DRender::Render::TextureDataManager *texDataMgr = mgrs->textureDataManager(); - QVERIFY(imgDataMgr->getData(idg1a) == nullptr); - QVERIFY(imgDataMgr->getData(idg2) == nullptr); - QVERIFY(texDataMgr->getData(tg1a) == nullptr); - QVERIFY(texDataMgr->getData(tg2) == nullptr); - - // WHEN - for (const auto gen : imgDataMgr->pendingGenerators()) - imgDataMgr->assignData(gen, (*gen)()); - for (const auto gen : texDataMgr->pendingGenerators()) - texDataMgr->assignData(gen, (*gen)()); - - // THEN - QVERIFY(imgDataMgr->getData(idg1a) != nullptr); - QVERIFY(imgDataMgr->getData(idg1b) != nullptr); - QVERIFY(imgDataMgr->getData(idg2) != nullptr); - QVERIFY(texDataMgr->getData(tg1a) != nullptr); - QVERIFY(texDataMgr->getData(tg1b) != nullptr); - QVERIFY(texDataMgr->getData(tg2) != nullptr); - - QCOMPARE(imgDataMgr->getData(idg1a), imgDataMgr->getData(idg1b)); - QVERIFY(imgDataMgr->getData(idg1a) != imgDataMgr->getData(idg2)); - - QCOMPARE(texDataMgr->getData(tg1a), texDataMgr->getData(tg1b)); - QVERIFY(texDataMgr->getData(tg1a) != texDataMgr->getData(tg2)); renderer.shutdown(); } @@ -447,23 +411,17 @@ private Q_SLOTS: QCOMPARE(img.isDirty(), false); QCOMPARE(img.face(), Qt3DRender::QAbstractTexture::CubeMapPositiveX); QVERIFY(img.dataGenerator().isNull()); - QVERIFY(img.textureImageDataManager() == nullptr); } void checkTextureImageCleanupState() { // GIVEN - QScopedPointer<Qt3DRender::Render::NodeManagers> mgrs(new Qt3DRender::Render::NodeManagers()); - Qt3DRender::Render::TextureManager *texMgr = mgrs->textureManager(); - Qt3DRender::Render::TextureImageDataManager *texImgDataMgr = mgrs->textureImageDataManager(); - TestTextureImage img(1); img.setLayer(2); img.setMipLevel(3); // WHEN Qt3DRender::Render::TextureImage texImgBackend; - texImgBackend.setTextureImageDataManager(texImgDataMgr); simulateInitialization(&img, &texImgBackend); texImgBackend.cleanup(); @@ -473,15 +431,11 @@ private Q_SLOTS: QCOMPARE(texImgBackend.mipLevel(), 0); QCOMPARE(texImgBackend.face(), Qt3DRender::QAbstractTexture::CubeMapPositiveX); QVERIFY(texImgBackend.dataGenerator().isNull()); - QVERIFY(texImgBackend.textureImageDataManager() != nullptr); } void checkTextureImageInitializeFromPeer() { // GIVEN - QScopedPointer<Qt3DRender::Render::NodeManagers> mgrs(new Qt3DRender::Render::NodeManagers()); - Qt3DRender::Render::TextureImageDataManager *texImgDataMgr = mgrs->textureImageDataManager(); - TestTextureImage img(1); { @@ -490,7 +444,6 @@ private Q_SLOTS: img.setMipLevel(3); Qt3DRender::Render::TextureImage texImgBackend; - texImgBackend.setTextureImageDataManager(texImgDataMgr); simulateInitialization(&img, &texImgBackend); // THEN @@ -508,7 +461,6 @@ private Q_SLOTS: img.setEnabled(false); Qt3DRender::Render::TextureImage texImgBackend; - texImgBackend.setTextureImageDataManager(texImgDataMgr); simulateInitialization(&img, &texImgBackend); // THEN @@ -520,12 +472,9 @@ private Q_SLOTS: void checkTextureImageSceneChangeEvents() { // GIVEN - QScopedPointer<Qt3DRender::Render::NodeManagers> mgrs(new Qt3DRender::Render::NodeManagers()); - Qt3DRender::Render::TextureImageDataManager *texImgDataMgr = mgrs->textureImageDataManager(); Qt3DRender::Render::TextureImage backendImage; TestRenderer renderer; backendImage.setRenderer(&renderer); - backendImage.setTextureImageDataManager(texImgDataMgr); { // WHEN @@ -601,7 +550,6 @@ private Q_SLOTS: // THEN QCOMPARE(backendImage.dataGenerator(), generator1); - QVERIFY(texImgDataMgr->contains(generator1)); QVERIFY(backendImage.isDirty()); QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); @@ -615,8 +563,6 @@ private Q_SLOTS: backendImage.sceneChangeEvent(change); // THEN - QVERIFY(!texImgDataMgr->contains(generator1)); - QVERIFY(texImgDataMgr->contains(generator2)); QVERIFY(backendImage.isDirty()); QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); @@ -630,8 +576,6 @@ private Q_SLOTS: backendImage.sceneChangeEvent(change); // THEN - QVERIFY(!texImgDataMgr->contains(generator1)); - QVERIFY(!texImgDataMgr->contains(generator2)); QVERIFY(backendImage.dataGenerator().isNull()); QVERIFY(backendImage.isDirty()); QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); @@ -648,7 +592,6 @@ private Q_SLOTS: Qt3DRender::Render::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous); Qt3DRender::Render::TextureManager *texMgr = mgrs->textureManager(); Qt3DRender::Render::TextureImageManager *texImgMgr = mgrs->textureImageManager(); - Qt3DRender::Render::TextureImageDataManager *texImgDataMgr = mgrs->textureImageDataManager(); renderer.setNodeManagers(mgrs.data()); // GIVEN @@ -667,13 +610,9 @@ private Q_SLOTS: // THEN QVERIFY(!frontendGenerator.isNull()); - QCOMPARE(texImgDataMgr->pendingGenerators().size(), 0); - QVERIFY(!texImgDataMgr->contains(frontendGenerator)); - QVERIFY(texImgDataMgr->getData(frontendGenerator).isNull()); // WHEN Qt3DRender::Render::TextureImage *texImgBackend = texImgMgr->getOrCreateResource(texImgFrontend->id()); - texImgBackend->setTextureImageDataManager(texImgDataMgr); simulateInitialization(texImgFrontend, texImgBackend); // THEN @@ -681,28 +620,6 @@ private Q_SLOTS: const Qt3DRender::QTextureImageDataGeneratorPtr backendGenerator = texImgFrontend->dataGenerator(); QVERIFY(frontendGenerator != backendGenerator); QVERIFY(*frontendGenerator == *backendGenerator); - QVERIFY(texImgDataMgr->contains(frontendGenerator)); - QVERIFY(texImgDataMgr->contains(backendGenerator)); - QVERIFY(texImgDataMgr->getData(frontendGenerator).isNull()); - QCOMPARE(texImgDataMgr->pendingGenerators().size(), 1); - - // WHEN - texImgDataMgr->assignData(frontendGenerator, (*frontendGenerator)()); - - // THEN - QVERIFY(!texImgDataMgr->getData(frontendGenerator).isNull()); - QVERIFY(!texImgDataMgr->getData(backendGenerator).isNull()); - QVERIFY(texImgDataMgr->getData(backendGenerator) == texImgDataMgr->getData(frontendGenerator)); - - // WHEN - texImgBackend->cleanup(); - - // THEN - QVERIFY(!texImgDataMgr->contains(frontendGenerator)); - QVERIFY(!texImgDataMgr->contains(backendGenerator)); - QCOMPARE(texImgDataMgr->pendingGenerators().size(), 0); - QVERIFY(texImgDataMgr->getData(frontendGenerator).isNull()); - QVERIFY(texImgDataMgr->getData(backendGenerator).isNull()); renderer.shutdown(); } |