summaryrefslogtreecommitdiffstats
path: root/src/render/renderers/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/renderers/opengl')
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp166
-rw-r--r--src/render/renderers/opengl/renderer/renderer_p.h7
-rw-r--r--src/render/renderers/opengl/textures/gltexture.cpp102
-rw-r--r--src/render/renderers/opengl/textures/gltexture_p.h43
-rw-r--r--src/render/renderers/opengl/textures/gltexturemanager_p.h17
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 &params)
{
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 &params);
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