diff options
Diffstat (limited to 'src/render/renderers/opengl')
-rw-r--r-- | src/render/renderers/opengl/renderer/renderer.cpp | 166 | ||||
-rw-r--r-- | src/render/renderers/opengl/renderer/renderer_p.h | 7 | ||||
-rw-r--r-- | src/render/renderers/opengl/textures/gltexture.cpp | 102 | ||||
-rw-r--r-- | src/render/renderers/opengl/textures/gltexture_p.h | 43 | ||||
-rw-r--r-- | src/render/renderers/opengl/textures/gltexturemanager_p.h | 17 |
5 files changed, 137 insertions, 198 deletions
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 |